package com.signway.swmediaplayerdemo;

import androidx.appcompat.app.AppCompatActivity;

import android.annotation.SuppressLint;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.os.Bundle;
import android.os.Handler;
import android.os.SystemClock;
import android.os.signway.SignwayManager;
import android.util.DisplayMetrics;
import android.view.WindowManager;
import android.util.Log;
import android.view.Choreographer;
import android.view.Display;
import android.view.KeyEvent;

import com.signway.swmediaplayer.utils.SystemProperties;
import com.signway.swmediaplayerdemo.databinding.ActivitySubtitleBinding;

import java.nio.ByteBuffer;
import java.util.Calendar;

public class SubtitleActivity extends AppCompatActivity {
    public static final String TAG = SubtitleActivity.class.getName();
    private ActivitySubtitleBinding binding;
    private SignwayManager sm;
    private Bitmap bitmap;
    private static final String subtitleH  = "横向滚动测试字幕，横向滚动测试字幕，横向滚动测试字幕，横向滚动测试字幕，横向滚动测试字幕，横向滚动测试字幕，横向滚动测试字幕，横向滚动测试字幕。";
    private static final String subtitleHR = "。幕字试测动滚向横，幕字试测动滚向横，幕字试测动滚向横，幕字试测动滚向横，幕字试测动滚向横，幕字试测动滚向横，幕字试测动滚向横，幕字试测动滚向横";
    private static final String subtitleV  = "纵向滚动测试字幕，纵向滚动测试字幕，纵向滚动测试字幕，纵向滚动测试字幕，纵向滚动测试字幕，纵向滚动测试字幕，纵向滚动测试字幕，纵向滚动测试字幕。";
    private static final String subtitleVR = "。幕字试测动滚向纵，幕字试测动滚向纵，幕字试测动滚向纵，幕字试测动滚向纵，幕字试测动滚向纵，幕字试测动滚向纵，幕字试测动滚向纵，幕字试测动滚向纵";

    private static boolean onDraw = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding = ActivitySubtitleBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());

        sm = getSystemService(SignwayManager.class);
//        sm.setRotationScreen(270);

        WindowManager windowManager = getWindow().getWindowManager();
        DisplayMetrics metrics = new DisplayMetrics();
        windowManager.getDefaultDisplay().getRealMetrics(metrics);
        int width = metrics.widthPixels;
        int height = metrics.heightPixels;
        Log.d(TAG, "width " + width + ", height " + height);

        int step = 4;

        binding.create0.setOnClickListener(v -> {
            bitmap = createSubtitle(subtitleHR);
            sm.subtitleInit(0, 1000, width, bitmap.getHeight(), bitmap, 0, step);
        });

        binding.create180.setOnClickListener(v -> {
            bitmap = createSubtitle(subtitleH);
            sm.subtitleInit(0, 1000, width, bitmap.getHeight(), bitmap, 2, step);
        });

        binding.create90.setOnClickListener(v -> {
            bitmap = createSubtitle(subtitleVR);

            Matrix matrix = new Matrix();
            matrix.preRotate(90);
            Bitmap bitmapRotate = Bitmap.createBitmap(bitmap, 0, 0 , bitmap.getWidth(), bitmap.getHeight(), matrix, false);

            sm.subtitleInit(1000, 0, bitmapRotate.getWidth(), height, bitmapRotate, 1, step);
        });

        binding.create270.setOnClickListener(v -> {
            bitmap = createSubtitle(subtitleV);

            Matrix matrix = new Matrix();
            matrix.preRotate(90);
            Bitmap bitmapRotate = Bitmap.createBitmap(bitmap, 0, 0 , bitmap.getWidth(), bitmap.getHeight(), matrix, false);

            sm.subtitleInit(1000, 0, bitmapRotate.getWidth(), height, bitmapRotate, 3, step);
        });

        binding.start.setOnClickListener(v -> {
            sm.subtitlePrepare();
            sm.subtitleFlush();
            onDraw = true;
            Choreographer.getInstance().postFrameCallback(frameCallback);
        });

        binding.flush.setOnClickListener(v -> {
            sm.subtitleFlush();
        });

        binding.stop.setOnClickListener(v -> {
            onDraw = false;
            Choreographer.getInstance().removeFrameCallback(frameCallback);
            sm.subtitleRelease();
        });
    }

    private int getSystemRotate() {
        String orientation = SystemProperties.get("ro.surface_flinger.primary_display_orientation");
        if (orientation.equals("ORIENTATION_90")) {
            return 90;
        }
        if (orientation.equals("ORIENTATION_180")) {
            return 180;
        }
        if (orientation.equals("ORIENTATION_270")) {
            return 270;
        }
        return 0;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_0) {
            sm.subtitleFlush();
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i(TAG, "onStart");
    }

    @Override
    protected void onStop() {
        super.onStop();
        Log.i(TAG, "onStop");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        Log.i(TAG, "onDestroy");
        Choreographer.getInstance().removeFrameCallback(frameCallback);
    }

    private long lastFrameTimeNanos;
    private Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() {
        @Override
        public void doFrame(long frameTimeNanos) {
            if (lastFrameTimeNanos > 0 && (frameTimeNanos - lastFrameTimeNanos > 17000000)) {
                Log.d(TAG, "Interval since last VSync: " + (frameTimeNanos - lastFrameTimeNanos) + " ns");
            }
            lastFrameTimeNanos = frameTimeNanos;

            long startMs = SystemClock.elapsedRealtime();
            if (onDraw) {
                sm.subtitleFlush();
            }
            if (SystemClock.elapsedRealtime() - startMs > 2) {
                Log.d(TAG, "subtitleFlush time " + (SystemClock.elapsedRealtime() - startMs));
            }
            Choreographer.getInstance().postFrameCallback(this);

            Calendar calendar = Calendar.getInstance();
            @SuppressLint("DefaultLocale")
            String text = String.format("%02d:%02d:%02d %03d",
                    calendar.get(Calendar.HOUR_OF_DAY),
                    calendar.get(Calendar.MINUTE),
                    calendar.get(Calendar.SECOND),
                    calendar.get(Calendar.MILLISECOND % 1000));
            binding.timeView.setText(text);

            FpsMonitor.get().updateFPS(frameTimeNanos);
        }
    };

    private Bitmap createSubtitle(String text) {
        int textWidth;
        int textHeight = 96;
        Bitmap bitmap;

        Paint bgRect=new Paint();
        bgRect.setStyle(Paint.Style.FILL);
        bgRect.setColor(Color.GRAY);

        Paint textPaint = new Paint();
        textPaint.setStyle(Paint.Style.FILL);
        textPaint.setStrokeWidth(8);
        textPaint.setTextSize(72);
        textPaint.setTextAlign(Paint.Align.CENTER);
        textPaint.setAntiAlias(true);
        textPaint.setColor(Color.BLACK);
        textWidth = (int) textPaint.measureText(text);
        bitmap = Bitmap.createBitmap(textWidth + 1, textHeight, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(bitmap);

        //计算baseline
        Paint.FontMetrics fontMetrics = textPaint.getFontMetrics();
        float distance = (fontMetrics.bottom - fontMetrics.top)/2 - fontMetrics.bottom;
        float baseline = textHeight / 2 + distance;
        c.drawText(text, textWidth / 2, baseline, textPaint);

        bgRect.setColor(Color.RED);
        c.drawLine(0, 0, bitmap.getWidth(), 0, bgRect);
        c.drawLine(0, 0, 0, bitmap.getHeight(), bgRect);
        c.drawLine(bitmap.getWidth() - 1, 0, bitmap.getWidth(), bitmap.getHeight(), bgRect);
        c.drawLine(0,  bitmap.getHeight() - 1, bitmap.getWidth(), bitmap.getHeight(), bgRect);

//        int bytes = bitmap.getByteCount();
//        ByteBuffer buffer = ByteBuffer.allocate(bytes);
//        bitmap.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
//        byte[] data = buffer.array(); //Get the bytes array of the bitmap
//        Log.d(TAG, "bitmap: " + byteToString(data, 100));

        return bitmap;
    }

    public static String byteToString(byte[] a, int len) {
        if (a == null)
            return "null";
        int iMax = a.length - 1;
        if (iMax == -1)
            return "[]";

        iMax = Math.min(len, iMax);

        StringBuilder b = new StringBuilder();
        b.append('[');
        for (int i = 0; ; i++) {
            b.append(a[i] & 0xFF);
            if (i == iMax)
                return b.append(']').toString();
            b.append(", ");
        }
    }

    public Bitmap cropCircle(Bitmap bitmap) {
        Bitmap output = Bitmap.createBitmap(bitmap.getWidth(),
                bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(output);
        final int color = 0xff424242;
        final Paint paint = new Paint();
        final Rect rect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
        paint.setAntiAlias(true);
        canvas.drawARGB(0, 0, 0, 0);
        paint.setColor(color);
        canvas.drawCircle(bitmap.getWidth() / 2, bitmap.getHeight() / 2,
                bitmap.getWidth()/2, paint);
        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
        canvas.drawBitmap(bitmap, rect, rect, paint);

        int bytes = output.getByteCount();
        ByteBuffer buffer = ByteBuffer.allocate(bytes);
        output.copyPixelsToBuffer(buffer); //Move the byte data to the buffer
        byte[] data = buffer.array(); //Get the bytes array of the bitmap
        Log.d(TAG, "");

        return output;
    }

}